using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace ValidationFramework.ActiveRecord
{
    /// <summary>
    /// Provides base class that developer can inherit from to provide <see cref="INotifyPropertyChanged"/> and <see cref="IDataErrorInfo"/> functionality for all sub-classes.
    /// </summary>
    /// <remarks>This ideal for windows forms applications to get immediate validation feedback on dataBound controls.</remarks>
    [Serializable]
    public abstract class ActiveRecordDataErrorInfoValidatableBase :ActiveRecordValidatableBase, IDataErrorInfo
    {



        #region Properties

        /// <summary>
        /// Gets an error message indicating what is wrong with this object. 
        /// </summary>
        /// <remarks>The uses <see cref="ResultFormatter.GetConcatenatedErrorMessages(ICollection{ValidationResult})"/> to merge the <see cref="ValidationResult.ErrorMessage"/>s of <see cref="ValidatableBase.ValidatorResultsInError"/>.</remarks>
        public virtual string Error
        {
            get
            {
                return ResultFormatter.GetConcatenatedErrorMessages(ValidatorResultsInError);
            }
        }




        /// <summary>
        /// Gets a <see lanword="bool"/> indicating if the current state is valid.
        /// </summary>
        /// <remarks>
        /// Since properties are validated when set, calling this property does not validate all properties.
        /// </remarks>
        public override bool IsValid
        {
            get
            {
                return PropertyValidationManager.IsValid;
            }
        }

        #endregion


        #region Methods

        /// <summary>
        /// Perform validation for specified property.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate. The parameter is case sensitive.</param>
        protected void ValidateProperty(string propertyName)
        {
            if (IgnoreNoRules)
            {
                PropertyValidationManager.TryValidate(propertyName);
            }
            else
            {
                PropertyValidationManager.Validate(propertyName);
            }
        }


        /// <summary>
        /// Gets the error message for the property with the given name. 
        /// </summary>
        /// <param name="columnName">The name of the property whose error message to get.  The parameter is case sensitive.</param>
        /// <returns>The error message for the property. The default is an <see cref="string.Empty"/>.</returns>
        public virtual string this[string columnName]
        {
            get
            {
                IList<ValidationResult> property;
                if (PropertyValidationManager.TryGetResultsInError(columnName, out property))
                {
                    var errors = new StringBuilder();
                    for (var propertyIndex = 0; propertyIndex < property.Count; propertyIndex++)
                    {
                        var validationResult = property[propertyIndex];
                        errors.AppendLine(validationResult.ErrorMessage);
                    }

                    return errors.ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
        }

        #endregion
    }
}